<?php
namespace EasyPhpWeb;

class CoreService{
    /**
     * @var false|resource
     */
    private $socket;

    private $config;

    private $address;

    private $staticDir;

    /**
     * @var []resource
     */
    private $socketList = [];

    private $dataBuffer = [];


    public function __construct($config)
    {
        $this->config = $config['service'];
        $this->address = $this->getAddress();
        $this->staticDir = dirname(__DIR__) . $this->config['staticDir'];

        $this->socket = @stream_socket_server($this->address, $errNo, $errMessage);
        if (!is_resource($this->socket)) {
            throw new \InvalidArgumentException("参数异常:" . $errMessage);
        }

        // stream_set_blocking 设置非阻塞io
        stream_set_blocking($this->socket, false);
        // 添加当前监听的socket
        $this->socketList[(int)$this->socket] = $this->socket;
    }

    private function getAddress(){

        $host = isset($this->config['host']) ? $this->config['host'] : "127.0.0.1";
        $port = isset($this->config['port']) ? $this->config['port'] : "9080";

        return "{$host}:{$port}";
    }

    /**
     * 启动服务器
     */
    public function run()
    {
        echo "this address: {$this->address}" . PHP_EOL;
        
        while (true) {
            $read  = $this->socketList;

            $write = $except = [];
            //阻塞监听 设置null阻塞监听
            $count = @stream_select($read, $write, $except, null);

            if ($count) {

                foreach ($read as $k => $v) {
                    if ($v == $this->socket) {
                        // connect success
                        // accept Connection
                        @$conn = stream_socket_accept($this->socket, null, $remote_address);
                        //echo "connect fd:" . $k . PHP_EOL;
                        $this->socketList[(int)$conn] = $conn;
                    } else {
                        $this->receiveHttp($v, $k);
                    }
                } 
            }
        }
    }

    protected function receiveHttp($stream, $k)
    {
        $length = 1024;
        $buffer = fread($stream, $length);

        $this->dataBuffer[$k] .= $buffer;
        if (empty($buffer) || strlen($buffer) < $length || feof($stream)) {

            $request = new Request();
            $response = new Response();
            $request->setStrRequest($this->dataBuffer[$k]);
            $request->analysis();

            if(is_file($this->staticDir . $request->uri)){
                var_dump("is file");
                $response->file($this->staticDir . $request->uri, $stream);
            } else {
                $view = "";
                try{
                    $view = Route::do($request->method, $request->uri, $request, $response);
                } catch (\Exception $e){
                    $view = json_encode([
                        "code" => $e->getCode(),
                        "message" => $e->getMessage()
                    ]);
                }
    
                $response->write($view, $stream);
            }

            //释放资源
            fclose($stream);
            unset($this->socketList[(int)$stream]);
            unset($this->dataBuffer[(int)$stream]);
            return ;
        } 
    }

    
    // protected function response($stream, $k){

    //     //var_dump("dataBuffer=", $this->dataBuffer[$k]);

    //     // //http server
    //     $data     = "Hello World";
    //     $response = "HTTP/1.1 200 OK\r\n";
    //     $response .= "Content-Type: text/html;charset=UTF-8\r\n";
    //     $response .= "Server: MyServer1\r\n";
    //     $response .= "Content-length: " . strlen($data) . "\r\n\r\n";
    //     $response .= $data;
    //     fwrite($stream, $response);
    // }
}